<script lang="ts" setup>
import { ref, reactive, computed, provide } from 'vue'
import CustomFormItem from '@/components/basic/CustomFormItem.vue'
import RefundAccountTypeFormItem from '@/components/basic/RefundAccountTypeFormItem.vue'
import { queryOrderRefundInfo, queryOrderDetailInfo } from '@/api/order'
import { submitCmRefundApply } from '@/api/expense'
import { validateMoney } from '@/utils/formvalidate'
import {
  OrderInfoType,
  queryOrderRefundInfoResponseData,
  queryOrderDetailInfoResponseData
} from '@/api/order/types/order'
import { getToken } from '@/utils/cache/cookies'
import TermInputNumberGroup from '@/components/basic/TermInputNumberGroup.vue'
import { OptionsType, AliPayRefundData, BankRefundData } from '@/types/interface'
import { ElMessage, FormInstance, FormRules } from 'element-plus'
import { defineAsyncComponent } from 'vue'

const dialogVisible = ref<boolean>(false)
const title = ref<string>('退款申请')
const open = () => {
  dialogVisible.value = true
}
// const setData = (phone: string, orderId: string, orderType: string, id: number) => {
//   form.phone = phone
//   form.orderId = orderId
//   type.value = orderType
//   userId.value = id
//   disabled.value = true
//   getOrderInfo()
// }
defineExpose({ open })
const form = reactive({
  phone: '',
  orderId: '',
  applyAmount: 0,
  accountType: '原路退回',
  applyReason: ''
})
const formRef = ref<FormInstance | null>(null)
const rules = reactive<FormRules>({
  phone: [{ required: true, message: '请输入用户手机号', trigger: 'blur' }],
  orderId: [{ required: true, message: '请选择订单号', trigger: 'change' }],
  applyAmount: [
    {
      required: true,
      validator: validateMoney,
      trigger: 'blur'
    }
  ],
  accountType: [{ required: true, message: '请选择退款渠道', trigger: 'change' }],
  applyReason: [{ required: true, message: '请输入退款原因', trigger: 'blur' }]
})
/** 根据用户手机号获取退款信息 */
const data = ref<(queryOrderRefundInfoResponseData & Record<string, any>) | null>(null)
const refundType = ref<OptionsType[]>([])
const batteryOrder = ref<OrderInfoType[] | undefined>([])
const bikeOrder = ref<OrderInfoType[] | undefined>([])
const OrderList = ref<OrderInfoType[]>([])
/** 根据选择的订单 查询订单信息  */
const orderData = ref<queryOrderDetailInfoResponseData | null>(null)
/** 依赖 */
provide(
  'bizType',
  computed(() => orderData.value?.bizType)
)
const getUserRefundInfo = async () => {
  try {
    if (!form.phone) return
    selectLoading.value = true
    const res = await queryOrderRefundInfo({
      token: getToken() ?? '',
      phone: form.phone,
      type: 'partial',
      orderId: form.orderId
    })
    if (res.statusCode === '0') {
      data.value = res.data
      refundType.value = res.data.refundType
      batteryOrder.value = res.data.batteryOrder
      bikeOrder.value = res.data.bikeOrder
      userId.value = res.data.userId
    }
    selectLoading.value = false
  } catch (error) {
    console.error(error)
    selectLoading.value = false
  }
}
const getOrderInfo = async () => {
  try {
    loading.value = true
    const res = await queryOrderDetailInfo({
      userId: userId.value.toString(),
      token: getToken() ?? '',
      orderId: form.orderId
    })
    if (res.statusCode === '0') {
      orderData.value = res.data
      handleTypeChange()
    }
    loading.value = false
  } catch (error) {
    console.error(error)
    loading.value = false
  }
}
/** 退款类型 */
const type = ref<string>('')
const userId = ref<number>(0)
/** 加载订单详情 */
const loading = ref<boolean>(false)
/** 请求用户订单 select加载 */
const selectLoading = ref<boolean>(false)
/** 操作类型 */
const applicationType = ref<'0' | '1'>('0')
provide(
  'type',
  computed(() => applicationType.value)
)
/** 退逾期费禁用 当canOverdue为1 */
const refundRentDisabled = computed(() => {
  return orderData.value?.canOverdue === 1
})
/** 是否显示退逾期费 */
const isShowOverDueRefund = computed(() => {
  return orderData.value?.canOverdue === 1 || orderData.value?.canOverdue === 2
})
const payStatusStyle = computed(() => {
  const payStatus = orderData.value?.bizData.payStatus ?? ''
  return {
    color: payStatus === '已支付' ? 'var(--xy-success-color)' : 'var(--xy-warning-color)'
  }
})
const isRefundRent = computed(() => {
  return applicationType.value === '0'
})
const isRentAndTimesCardType = computed(() => {
  return orderData.value?.bizType === 'BatteryTimesCard' && applicationType.value === '0'
})
const isRentAndDaysType = computed(() => {
  return orderData.value?.bizType !== 'BatteryTimesCard' && applicationType.value === '0'
})
/** 请求后 将最大值给到退款金额计算 */
const handleTypeChange = () => {
  if (isRentAndTimesCardType.value) {
    times.value = maxValues.value.time
  } else if (isRentAndDaysType.value) {
    DateForm.day = maxValues.value.day
    DateForm.hour = maxValues.value.hour
    DateForm.minute = maxValues.value.minute
  } else {
    overdueDay.value = maxValues.value.overdueDay
  }
}
/** 退款金额计算 */
interface DateFormType {
  day: number
  minute: number
  hour: number
}
const DateForm = reactive<DateFormType>({
  day: 0,
  minute: 0,
  hour: 0
})
const overdueDay = ref<number>(0)
const times = ref<number>(0)
const maxValues = computed(() =>
  parseRemainingTime(orderData.value?.orderSummary.originRemainingTime ?? '-')
)
const RefundAmountCalculateFormItem = defineAsyncComponent(
  () => import('@/components/basic/RefundAmountCalculate.vue')
)
// 解析 remainTime 字段 得到
const parseRemainingTime = (remainingTime: string) => {
  const timeValues = { day: 0, hour: 0, minute: 0, time: 0, overdueDay: 0 }
  if (remainingTime === '-') return timeValues
  if (applicationType.value === '0' && orderData.value?.bizType !== 'BatteryTimesCard') {
    const dayMatch = remainingTime.match(/(\d+)\s*天/)
    const hourMatch = remainingTime.match(/(\d+)\s*(小时|时)/)
    const minuteMatch = remainingTime.match(/(\d+)\s*(分钟|分)/)

    timeValues.day = dayMatch ? parseInt(dayMatch[1], 10) : 0
    timeValues.hour = hourMatch ? parseInt(hourMatch[1], 10) : 0
    timeValues.minute = minuteMatch ? parseInt(minuteMatch[1], 10) : 0
    return timeValues
  } else if (applicationType.value === '0' && orderData.value?.bizType === 'BatteryTimesCard') {
    const timesMatch = remainingTime.match(/(\d+)\s*次/)
    timeValues.time = timesMatch ? parseInt(timesMatch[1], 10) : 0
    return timeValues
  } else {
    const dayMatch = remainingTime.match(/(\d+)\s*天/)
    timeValues.overdueDay = dayMatch ? parseInt(dayMatch[1], 10) : 0
    return timeValues
  }
}
/** 切换退款类型时 切换订单号选项 */
const handleChangeType = () => {
  form.orderId = ''
  OrderList.value = data.value![type.value]
}
/** 选择退款渠道时 支付宝数据或者银行卡数据 */
const AliAccountData = reactive<AliPayRefundData & Record<string, any>>({
  aliName: '',
  aliAccount: ''
})
const BankAccountData = reactive<BankRefundData & Record<string, any>>({
  bankName: '',
  bankBranchName: '',
  username: '',
  card: ''
})
/** 计算可退租金 */
const canRefundRentForAmount = computed(() => {
  if (!isRefundRent.value) {
    return orderData.value?.orderRefundData.resultData.remainingRefundAmountOverdue ?? 0
  } else {
    return orderData.value?.orderRefundData.resultData.remainingRefundAmountRent ?? 0
  }
})
/** 当取消弹框时 */
const handleClose = () => {
  formRef.value?.resetFields()
  data.value = null
  refundType.value = []
  batteryOrder.value = []
  bikeOrder.value = []
  orderData.value = null
  userId.value = 0
  type.value = ''
  OrderList.value = []
  for (const key in AliAccountData) {
    if (Object.prototype.hasOwnProperty.call(AliAccountData, key)) {
      AliAccountData[key] = ''
    }
  }
  for (const key in BankAccountData) {
    if (Object.prototype.hasOwnProperty.call(BankAccountData, key)) {
      BankAccountData[key] = ''
    }
  }
}
/** 是否传入accountData */
const AccountData = computed(() => {
  if (form.accountType === '原路退回') return
  if (form.accountType === '支付宝') {
    return AliAccountData
  } else {
    return BankAccountData
  }
})
/** 打开支付宝权限dialog */
const AliPayPermissionDialog = defineAsyncComponent(
  () => import('@/components/dialog/AliPayPermission.vue')
)
const AliPayPermissionDialogRef = ref<InstanceType<typeof AliPayPermissionDialog> | null>(null)
const handleOpen = () => {
  AliPayPermissionDialogRef.value?.open()
}
/** 套餐时长/次数 */
const isReduceTerm = ref<boolean>(false)
const termDateForm = reactive<DateFormType>({
  day: 0,
  minute: 0,
  hour: 0
})
const termOverdueDay = ref<number>(0)
const termTimes = ref<number>(0)
const termMaxValues = computed(() =>
  parseRemainingTime(orderData.value?.orderSummary.originRemainingTime ?? '-')
)
const allInApplyAmount = () => {
  form.applyAmount = canRefundRentForAmount.value
}
/**
 * @description 提交表单
 * @todo 待验证
 */
const submitReduceTerm = computed(() => {
  if (isRentAndTimesCardType.value) {
    return {
      times: termTimes.value
    }
  } else if (isRentAndDaysType.value) {
    return {
      ...termDateForm
    }
  } else {
    return {
      day: termOverdueDay.value
    }
  }
})
const submitType = computed(() =>
  isReduceTerm.value ? (applicationType.value === '1' ? '4' : '3') : ''
)
const handleSubmit = () => {
  formRef.value?.validate((valid: boolean) => {
    if (valid) {
      submitCmRefundApply({
        token: getToken() ?? '',
        applyType: 'PARTIAL_REFUND',
        type: submitType.value,
        accountData: AccountData.value,
        orderId: form.orderId,
        applyAmount: form.applyAmount,
        applyReason: form.applyReason,
        accountType: form.accountType,
        ...submitReduceTerm.value
      })
        .then((res) => {
          if (res.statusCode === '0') {
            ElMessage.success(res.data)
            dialogVisible.value = false
          }
        })
        .catch((error) => {
          console.error(error)
        })
    }
  })
}
</script>

<template>
  <el-dialog
    v-model="dialogVisible"
    :title="title"
    width="850px"
    class="deposit-refund-application-dialog"
    @close="handleClose"
  >
    <el-form :model="form" label-width="120px" ref="formRef" :rules="rules" v-loading="loading">
      <el-form-item prop="phone" label="用户手机号:">
        <el-input v-model="form.phone" @change="getUserRefundInfo" />
      </el-form-item>
      <el-form-item label="退款类型:">
        <el-select
          v-model="type"
          @change="handleChangeType"
          :loading="selectLoading"
          remote
          :remote-method="getUserRefundInfo"
        >
          <el-option
            v-for="({ label, value }, index) in refundType"
            :key="index"
            :label="label"
            :value="value"
          />
        </el-select>
      </el-form-item>
      <el-form-item prop="orderId" label="订单:">
        <el-select v-model="form.orderId" @change="getOrderInfo">
          <el-option
            v-for="({ orderId, name }, index) in OrderList"
            :key="index"
            :label="orderId + '(' + name + ')'"
            :value="orderId"
          />
        </el-select>
      </el-form-item>
      <Transition mode="out-in">
        <div v-if="orderData">
          <el-form-item label="操作类型">
            <el-radio-group v-model="applicationType" @change="handleTypeChange">
              <el-radio label="退租金" value="0" />
              <el-radio
                label="退逾期费"
                value="1"
                v-if="isShowOverDueRefund"
                :disabled="refundRentDisabled"
              />
            </el-radio-group>
          </el-form-item>
          <template v-if="isRefundRent">
            <custom-form-item>
              <template #label>
                <span>租金时长/次数:</span>
              </template>
              <template #value>
                <span
                  >{{ orderData.productSnapshot.rentTimeDescription }} *
                  {{ orderData.productCount }}</span
                >
              </template>
              <template #label2>
                <span>剩余时长/次数:</span>
              </template>
              <template #value2>
                <span
                  >{{ orderData.orderSummary.RemainingTime }}
                  <span>(其中包含{{ orderData.orderSummary.giftTime }}不可退)</span>
                </span>
              </template>
            </custom-form-item>
            <custom-form-item>
              <template #label>
                <span>租金金额:</span>
              </template>
              <template #value>
                <span
                  >{{ orderData.productPrice }}
                  <span :style="payStatusStyle">({{ orderData.bizData.payStatus }})</span>
                </span>
              </template>
              <template #label2>
                <span>可退租金:</span>
              </template>
              <template #value2>
                <span class="text-warning-light">{{ canRefundRentForAmount }}元 </span>
              </template>
            </custom-form-item>
          </template>
          <template v-else>
            <custom-form-item>
              <template #label>
                <span>已支付逾期天数:</span>
              </template>
              <template #value>
                <span>{{ orderData.overdueData?.overdueDays }}</span>
              </template>
              <template #label2>
                <span>已支付逾期金额:</span>
              </template>
              <template #value2>
                <span>{{ orderData.overdueData?.totalOverdueAmount }} 元</span>
              </template>
            </custom-form-item>
          </template>
          <refund-amount-calculate-form-item
            v-model:form="DateForm"
            v-model:max-values="maxValues"
            v-model:overdue-day="overdueDay"
            v-model:times="times"
            :biz-type="orderData.bizType"
            :type="applicationType"
            :order-id="form.orderId"
          />
          <el-form-item label="套餐时长/次数">
            <el-radio-group v-model="isReduceTerm" items-start flex-col>
              <el-radio :value="true">
                <template #default>
                  <span>扣除</span>
                  <term-input-number-group
                    :is-control="true"
                    v-model:form="termDateForm"
                    v-model:max-values="termMaxValues"
                    v-model:overdue-day="termOverdueDay"
                    v-model:times="termTimes"
                  />
                </template>
              </el-radio>
              <el-radio :value="false">
                <template #default>
                  <span>不扣除</span>
                </template>
              </el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item prop="applyAmount" label="退款金额:">
            <el-input v-model="form.applyAmount" type="number">
              <template #prepend>￥</template>
            </el-input>
            <span class="text-[12px] text-[#999999]"
              >最多可退{{ canRefundRentForAmount }},<span
                class="text-[#FF6D75] cursor-pointer"
                @click="allInApplyAmount"
                >全部填入</span
              >,最多可退金额={{ isRefundRent ? '可退租金' : '已支付的逾期金额' }}</span
            >
          </el-form-item>
          <el-form-item prop="applyReason" label="退款原因">
            <el-input
              v-model="form.applyReason"
              type="textarea"
              :min="2"
              placeholder="请输入退款原因"
            />
          </el-form-item>
          <refund-account-type-form-item
            -ali-value="支付宝"
            -bank-value="银行卡"
            -origin-value="原路退回"
            v-model="form"
            v-model:alipay="AliAccountData"
            v-model:bank="BankAccountData"
            :apartTime="orderData?.orderRefundData.apartTime ?? true"
            @open="handleOpen"
          />
        </div>
      </Transition>
    </el-form>
    <template #footer>
      <el-button plain @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" @click="handleSubmit">确定</el-button>
    </template>
  </el-dialog>
  <ali-pay-permission-dialog ref="AliPayPermissionDialogRef" />
</template>

<style scoped lang="scss">
:deep(.el-radio:not(.is-checked) > .el-radio__label span) {
  color: #cccccc;
}
:deep(.el-radio:not(.is-checked) > .el-radio__label .el-input__inner) {
  color: #cccccc;
}
:deep(.el-input-number.is-controls-right) {
  width: 60px;
}
:deep(.el-input-number.is-controls-right .el-input__wrapper) {
  padding-left: 15px;
  padding-right: 21px;
}
:deep(.el-input-number__increase) {
  width: 16px;
  border: none !important;
  background: var(--xy-white-color);
}
:deep(.el-input-number__decrease) {
  width: 16px;
  border: none !important;
  background: var(--xy-white-color);
}
.el-radio__input.is-checked + .el-radio__label > span:first-child {
  color: var(--el-color-primary);
}
.el-radio__input + .el-radio__label > span:first-child {
  margin-right: 5px;
}
:deep(.el-radio__input.is-checked + .el-radio__label) {
  color: var(--xy-medium-text-color);
}
</style>
